package com.caiyi.financial.nirvana.sms.jedis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * redis服务
 *
 * @author lvchaohua
 */
public class JedisService {

    private JedisService() {
    }

    private static Logger logger = LoggerFactory.getLogger(JedisService.class);

    private static JedisPool jedisPool;

    public static void init(String host, int port, int maxTotal, int maxIdle, long maxWaitMillis, int timeout) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMaxWaitMillis(maxWaitMillis);
        config.setTestOnBorrow(true);
        config.setTestOnCreate(true);
        config.setTestOnReturn(true);
        config.setTestWhileIdle(true);
        jedisPool = new JedisPool(config, host, port, timeout);
    }

    public static void shutdown() {
        logger.info("JedisPool server shutdown!");
        if (jedisPool != null) {
            jedisPool.destroy();
        }
    }

    public static Jedis getJedis() {
        try {
            return jedisPool.getResource();
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static void close(Jedis jedis) {
        try {
            if (jedis != null) {
                jedis.close();
            }
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static Map<String, String> hgetAll(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hgetAll(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.set(key, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String get(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.get(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long del(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.del(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long del(String[] keys) {
        Jedis jedis = null;
        try {
            if (keys == null || keys.length == 0) {
                return 0;
            }
            jedis = getJedis();
            return jedis.del(keys);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static boolean exists(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.exists(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Long lrem(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lrem(key, 0, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static List<String> lrange(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lrange(key, 0, -1);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long lpush(String key, String... strings) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lpush(key, strings);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long rpush(String key, String... strings) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.rpush(key, strings);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String lpop(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lpop(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static List<String> brpop(int timeout, String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.brpop(timeout, key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String rpop(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.rpop(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String rpoplpush(String srckey, String dstkey) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.rpoplpush(srckey, dstkey);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String rpoplpush(String key) {
        try {
            return rpoplpush(key, key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static String hmset(String key, Map<String, String> hash) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hmset(key, hash);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hset(key, field, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String hget(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hget(key, field);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long hincrBy(String key, String field, long value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hincrBy(key, field, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long incrBy(String key, long value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.incrBy(key, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long publish(String channel, String message) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.publish(channel, message);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long sadd(String key, String... members) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.sadd(key, members);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long srem(String key, String... members) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.srem(key, members);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long expire(String key, int seconds) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.expire(key, seconds);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static double hincrByFloat(String key, String field, Double value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hincrByFloat(key, field, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static List<String> lrange(String key, int start, int end) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lrange(key, start, end);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Set<String> smembers(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.smembers(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long hdel(String key, String... fields) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hdel(key, fields);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Set<String> keys(String pattern) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.keys(pattern);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String flushAll() {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.flushAll();
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long dbSize() {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.dbSize();
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static long llen(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.llen(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static boolean sismember(String key, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.sismember(key, member);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Long setnx(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.setnx(key, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static String setex(String key, int seconds, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.setex(key, seconds, value);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Long zadd(String key, Map<String, Double> scoreMembers) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zadd(key, scoreMembers);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Long incr(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.incr(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Long decr(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.decr(key);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static void subscribe(JedisPubSub jedisPubSub, String channels) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.subscribe(jedisPubSub, channels);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public static Set<String> zrevrange(String key, long start, long end) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zrevrange(key, start, end);
        } catch (Exception e) {
            logger.error("jedis error " + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

}